home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / dict / _ch_hash.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  4.4 KB  |  251 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _ch_hash.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/ch_hash.h>
  16.  
  17. //------------------------------------------------------------------------------
  18. //
  19. //  hashing with chaining
  20. //
  21. //  S. Naeher (1994)
  22. //
  23. //------------------------------------------------------------------------------
  24.  
  25.  
  26. ch_hash_elem ch_hash::STOP;
  27.  
  28.  
  29. int ch_hash::next_pow(int x) const
  30. { // return next power of 2
  31.   int result = 1;    
  32.   while ((x>>=1) > 0) result <<= 1;
  33.   return result;
  34.  }
  35.  
  36.  
  37. ch_hash_item ch_hash::search(GenPtr x, ch_hash_item& pred) const
  38. { register ch_hash_item p;
  39.  
  40.   STOP.k = x;
  41.  
  42.   if (int_type())
  43.   { p = table + (int(x) & table_size_1);  // table_size = power of 2
  44.     while (p->succ->k != x) p = p->succ;
  45.    }
  46.   else
  47.   { p = table + (hash_fct(x) & table_size_1);
  48.     while (cmp(p->succ->k,x) != 0) p = p->succ;
  49.    }
  50.  
  51.   pred = p;
  52.  
  53.   return p->succ;
  54. }
  55.  
  56.  
  57. ch_hash_item ch_hash::lookup(GenPtr x) const
  58. { register ch_hash_item q;
  59.  
  60.   STOP.k = x;
  61.  
  62.   if (int_type())
  63.   { q = table[int(x) & table_size_1].succ;  // table_size = power of 2
  64.     while (q->k != x) q = q->succ;
  65.    }
  66.   else
  67.   { q = table[hash_fct(x) & table_size_1].succ;
  68.     while (cmp(q->k,x)) q = q->succ;
  69.    }
  70.  
  71.   return (q == &STOP) ? 0 : q;
  72. }
  73.  
  74.  
  75. void ch_hash::change_inf(ch_hash_item p, GenPtr x)
  76. { clear_inf(p->i);
  77.   p->i = x;
  78.   copy_inf(p->i);
  79.  }
  80.  
  81. void ch_hash::del(GenPtr x)
  82. { ch_hash_item p;
  83.   ch_hash_item q = search(x,p);
  84.  
  85.   if (q==&STOP) return;
  86.  
  87.   clear_key(q->k);
  88.   clear_inf(q->i);
  89.  
  90.   p->succ = q->succ;
  91.   delete q;
  92.   count--;
  93.   if (count == low_table) rehash(low_table);
  94.  }
  95.  
  96.  
  97. void ch_hash::del_item(ch_hash_item q)
  98. { register ch_hash_item p = table + (hash_fct(q->k) & table_size_1);
  99.   while(p->succ != q) p = p->succ;
  100.   clear_key(q->k);
  101.   clear_inf(q->i);
  102.   p->succ = q->succ;
  103.   delete q;
  104.   count--;
  105.   if (count == low_table) rehash(low_table);
  106.  }
  107.   
  108.   
  109.   
  110.  
  111. ch_hash_item ch_hash::insert(GenPtr x, GenPtr y)
  112. { ch_hash_item p;
  113.   ch_hash_item q = search(x,p);
  114.  
  115.   if (q != &STOP)
  116.   { clear_inf(q->i);
  117.     q->i = y;
  118.     copy_inf(q->i);
  119.     return q;
  120.    }
  121.  
  122.    copy_key(x);
  123.    copy_inf(y);
  124.  
  125.    q = new ch_hash_elem(x,y,&STOP);
  126.    q->succ = &STOP;
  127.    p->succ = q;
  128.  
  129.    count++;
  130.  
  131.    if (count == high_table) rehash(high_table);
  132.  
  133.    return q;
  134.  
  135. }
  136.  
  137.  
  138.  
  139. void ch_hash::destroy()
  140.   for(int i=0; i < table_size; i++) 
  141.   { ch_hash_item p = table[i].succ;
  142.     ch_hash_item q = p;
  143.     while (p != &STOP)
  144.     { clear_key(p->k);
  145.       clear_inf(p->i);
  146.       q = p;
  147.       p = p->succ;
  148.       delete q;
  149.     }
  150.    }
  151.   //delete[] table;
  152.   free(table);
  153. }
  154.  
  155.  
  156. void ch_hash::init(int T)
  157. { register int i;
  158.  
  159.   table_size   = T;
  160.   table_size_1 = T-1;
  161.  
  162.   low_table  = (table_size > 1024) ? table_size >> 1 : -1;
  163.   high_table = table_size << 1;
  164.  
  165.  
  166.   //table = new ch_hash_elem[table_size];
  167.   table = (ch_hash_elem*)malloc(table_size*sizeof(ch_hash_elem));
  168.  
  169.   for(i=0; i<table_size; i++) table[i].succ = &STOP;
  170.  
  171.   count = 0;
  172. }
  173.  
  174.  
  175. void ch_hash::rehash(int T)
  176.   if (T == table_size) return;
  177.  
  178.   register ch_hash_item p;
  179.   register ch_hash_item q;
  180.   register ch_hash_item r;
  181.  
  182.   ch_hash_item old_table = table;
  183.   int old_table_size = table_size;
  184.   int old_count = count;
  185.  
  186.   init(T);
  187.  
  188.   if (int_type())
  189.    { for (int i=0; i<old_table_size; i++)
  190.      { p = old_table[i].succ;
  191.        while(p != &STOP)
  192.        { r = p->succ;
  193.          q = table + (int(p->k) & table_size_1);
  194.          p->succ = q->succ;
  195.          q->succ = p;
  196.          p = r;
  197.         }
  198.       }
  199.     }
  200.   else
  201.    { for (int i=0; i<old_table_size; i++)
  202.      { p = old_table[i].succ;
  203.        while(p != &STOP)
  204.        { r = p->succ;
  205.          q = table + (hash_fct(p->k) & table_size_1);
  206.          p->succ = q->succ;
  207.          q->succ = p;
  208.          p = r;
  209.         }
  210.       }
  211.     }
  212.  
  213.   count = old_count;
  214.  
  215.   //delete[] old_table;
  216.   free(old_table);
  217. }
  218.  
  219.  
  220. ch_hash::ch_hash(const ch_hash& D)
  221. { ch_hash_item p;
  222.   init(D.table_size);
  223.   for (int i=0; i<table_size; i++)
  224.   { p = D.table[i].succ;
  225.     while(p != &STOP)
  226.     { insert(p->k,p->i);
  227.       D.copy_key(p->k);
  228.       D.copy_inf(p->i);
  229.       p = p->succ;
  230.     }
  231.   }
  232. }
  233.  
  234.  
  235. ch_hash& ch_hash::operator=(const ch_hash& D)
  236. { ch_hash_item p;
  237.   clear();
  238.   for (int i=0; i<D.table_size; i++)
  239.   { p = D.table[i].succ;
  240.     while(p != &STOP)
  241.     { insert(p->k,p->i);
  242.       p = p->succ;
  243.      }
  244.    }
  245.   return *this;
  246. }
  247.  
  248.